/*
 * gstreamer.c
 *
 *  Created on: 2010-9-30
 *      Author: jack
 */

#include <gst/gst.h>
#include "../include/structs.h"
#include "../include/player.h"


static GstElement *pipeline=NULL;
static GstBus *bus;
static songinfo *cursong;
static songinfo *head;

static int next_song()
{
	if(cursong->next!=NULL)
	{
		cursong=cursong->next;
		gst_element_set_state(pipeline,GST_STATE_NULL);
		g_object_set(G_OBJECT(pipeline),"uri",cursong->url,NULL);
		gst_element_set_state(pipeline,GST_STATE_PLAYING);
		get_lyric_xml();
	}
	else
	{
		gst_element_set_state(pipeline,GST_STATE_READY);
	}
	return 0;
}

static int prev_song()
{
	if(cursong->prev->prev!=NULL)
	{
		cursong=cursong->prev;
		gst_element_set_state(pipeline,GST_STATE_NULL);
		g_object_set(G_OBJECT(pipeline),"uri",cursong->url,NULL);
		gst_element_set_state(pipeline,GST_STATE_PLAYING);
		get_lyric_xml();
	}
	else
	{
		gst_element_set_state(pipeline,GST_STATE_READY);
	}
	return 0;
}

static gboolean bus_watcher(GstBus *bus,GstMessage *msg,gpointer date)
{
	switch(GST_MESSAGE_TYPE(msg))
	{
		case GST_MESSAGE_EOS:
			/*g_print("End Of Stream.\n");*/
			next_song();
			change_info(cursong);
			break;
		case GST_MESSAGE_ERROR:
		{
			gchar *debug;
			GError *error;

			gst_message_parse_error(msg,&error,&debug);
			g_free(debug);
			g_printerr("Error:%s\n",error->message);
			g_error_free(error);
			/*g_main_loop_quit(loop);*/
			break;
		}
		/*case GST_MESSAGE_BUFFERING:
		{
		    gint percent = 0;
		    gint64 pos=0;
		    GstFormat format=GST_FORMAT_DEFAULT;
		    gst_message_parse_buffering (msg, &percent);
		    g_print("Buffering (%u percent done)\n",percent);
		    gst_element_query_position(pipeline,&format,&pos);
		    g_print("Current Position:%ld \n",pos);
		    break;
		}*/
		default:
		{
			break;
		}
	}
	return TRUE;

}

int init_pipeline(songinfo *headinfo)
{
	head=headinfo;
	cursong=head->next;
	if(pipeline!=NULL)
	{
		gst_element_set_state(pipeline,GST_STATE_NULL);
		gst_object_unref(GST_OBJECT(pipeline));
	}
	gst_init(NULL,NULL);

	pipeline=gst_element_factory_make("playbin2","play");

	g_object_set(G_OBJECT(pipeline),"uri",cursong->url,NULL);

	bus=gst_pipeline_get_bus(GST_PIPELINE(pipeline));

	gst_bus_add_watch(bus,bus_watcher,NULL);
	gst_object_unref(bus);

	gst_element_set_state(pipeline,GST_STATE_READY);

	return 0;
}

int play()
{
	gst_element_set_state(pipeline,GST_STATE_PLAYING);
	get_lyric_xml();
	return 0;
}

int pause()
{
	gst_element_set_state(pipeline,GST_STATE_PAUSED);
	return 0;
}

int stop()
{
	gst_element_set_state(pipeline,GST_STATE_READY);
	return 0;
}

int next()
{
	next_song();
	change_info(cursong);
	return 0;
}

int prev()
{
	prev_song();
	change_info(cursong);
	return 0;
}

int destory_pipeline()
{
	if(pipeline!=NULL)  /*gtk_widget_destroy会致使此方法被调用两次，所以要加入判断!!!!*/
	{
		gst_element_set_state(pipeline,GST_STATE_NULL);

		gst_object_unref(GST_OBJECT(pipeline));

		pipeline=NULL;/*Reset pipeline to NULL!!!!!*/
	}
	return 0;
}

double get_volume()
{
	double result=0;
	g_object_get (G_OBJECT (pipeline), "volume", &result, NULL);
	return result;
}

int set_volume(double volumeval)
{
	g_object_set (G_OBJECT (pipeline), "volume", volumeval, NULL);
	return 0;
}

int get_time(char *formated_time,char *lyric_time)
{
	GstFormat fmt = GST_FORMAT_TIME;
	gint64 pos,dur;
	char orig_time[100];

	if (gst_element_query_position (pipeline, &fmt, &pos)&&gst_element_query_duration (pipeline, &fmt, &dur))
	{
		g_sprintf(orig_time,"%u:%02u:%02u.%09u / %u:%02u:%02u.%09u\r",GST_TIME_ARGS (pos), GST_TIME_ARGS (dur));

		int i;
		/*格式化时间，去除毫秒部分*/
		/*generate time for time-display*/
		if(formated_time!=NULL)
		{
			char temp1[20];
			char temp2[20];
			for(i=0;i<7;i++)
			{
				temp1[i]=orig_time[i];
			}
			temp1[i]='\0';
			for(i=20;i<27;i++)
			{
				temp2[i-20]=orig_time[i];
			}
			temp2[i-20]='\0';
			g_sprintf(formated_time,"%s / %s",temp1,temp2);
		}

		/*generate formated time for lyric*/
		else
		{
			char temp3[20];
			for(i=2;i<10;i++)
			{
				temp3[i-2]=orig_time[i];
			}
			temp3[i-2]='\0';
			strcpy(lyric_time,temp3);/*return time for lyric*/
		}
		return 0;
	}
	else
	{
		if(lyric_time!=NULL)
		{
			strcpy(lyric_time,"");
		}
		return -1;
	}

}

char *get_song_id()
{
	return cursong->id;
}


/*double get_duration()
{
	GstFormat fmt=GST_FORMAT_TIME;
	gint64 len=0;
	while(!gst_element_query_duration (pipeline,&fmt, &len))
	{
		;
	}
	return (double)len;
}

int seek_position(double position)
{
	int count=0;
	while(!(gst_element_seek(pipeline,1.0,GST_FORMAT_TIME,GST_SEEK_FLAG_KEY_UNIT,GST_SEEK_TYPE_SET,position,GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))&&count<2000)
	{
		count++;
	}
}


unable to seek unless the stream server supports it!!!

*/
